home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1996
/
MacHack 1996.toast
/
Hacks
/
Hacks ’95
/
TrashHack
/
SizeTrashCan.c
< prev
next >
Wrap
Text File
|
1995-06-24
|
4KB
|
187 lines
#include <Files.h>
#include <Folders.h>
#include <Memory.h>
#include <TextUtils.h>
#define kMaxVolsChecked 10
static void SizeTrashCan (StringPtr sizeString);
static long SizeDirectory (short vRefNum, long dirID);
pascal void
TrashHack (StringPtr sizeString)
{
if (EqualString (sizeString, "\pTrash", false, false))
{
SizeTrashCan (sizeString);
}
}
void
SizeTrashCan (StringPtr sizeString)
{
short vRefNum;
short trashVRefNum;
short i;
long trashDirID;
long trashSize;
Str31 buffer;
HVolumeParam vpb;
// initialise the trash size
trashSize = 0;
// initialise (ignored) volume name
buffer [0] = 0;
// for each mounted volume
for (i = 0; i < kMaxVolsChecked; i++)
{
// get vRefNum of nth mounted volume
vpb.ioCompletion = nil;
vpb.ioVolIndex = i + 1;
vpb.ioNamePtr = buffer;
// get vol info
if (PBHGetVInfo ((HParmBlkPtr) &vpb, false) == noErr)
{
// check volume is online
if (vpb.ioVDRefNum < 0)
{
// extract volume refnum
vRefNum = vpb.ioVRefNum;
// find the trashcan
if (FindFolder (vRefNum, kTrashFolderType, kDontCreateFolder,
&trashVRefNum, &trashDirID) == noErr)
{
// we have a trash can!
// increment the total
trashSize += SizeDirectory (trashVRefNum, trashDirID);
}
else
{
// can't FindFolder on trashcan
}
}
else
{
// volume is offline
}
}
else
{
// can't PBHGetVInfo
}
}
if (trashSize)
{
// over a megabyte?
if (trashSize > (1024L * 1024L))
{
// give size in megabytes
NumToString (trashSize / (1024L * 1024L), buffer);
buffer [++buffer [0]] = 'M';
}
else
{
// give size in kilobytes
NumToString (trashSize / 1024L, buffer);
buffer [++buffer [0]] = 'K';
}
// check length is •exactly• right
if (buffer [0] <= 5)
{
while (buffer [0] < 5)
{
buffer [++buffer [0]] = ' ';
}
BlockMoveData (buffer, sizeString, 6);
}
}
else
{
// otherwise the string is a misleading “0K”
BlockMoveData ("\pzeroK", sizeString, 6);
}
}
// returns the combined size of the entries within the specified directory
// calls itself if it finds a directory beneath the specified directory
// “topLevel” parameter specifies whether this is the first iteration
// used as a check to see whether the trashcan has been modified since last call
static long
SizeDirectory (short vRefNum, long dirID)
{
OSErr errCode;
CInfoPBRec pb;
Str31 nameBuffer;
long totalSize = 0;
unsigned short numItems;
unsigned short i;
// make up a GetCatInfo paramblock
// to get info on the directory whose ID we are passed
pb.dirInfo.ioCompletion = nil;
pb.dirInfo.ioNamePtr = nameBuffer;
pb.dirInfo.ioVRefNum = vRefNum;
pb.dirInfo.ioFDirIndex = -1;
pb.dirInfo.ioDrDirID = dirID;
// get cat info!
errCode = PBGetCatInfo (&pb, false);
// check error code
if (errCode != noErr)
{
// oops - can't get info for this directory - return zero size
return 0;
}
// find out how many entries we have in the directory
numItems = pb.dirInfo.ioDrNmFls;
// loop thru each - the index starts at 1, remember
for (i = 1; i <= numItems; i++)
{
// configure the paramblock appropriately
// note have to reinitialise the dirID field every time
pb.dirInfo.ioFDirIndex = i;
pb.dirInfo.ioDrDirID = dirID;
// get the stuff about the file/dir
errCode = PBGetCatInfo (&pb, false);
// check error code
if (errCode != noErr)
{
// oops - can't get info on this entry
// leave well alone
continue;
}
// if it's a directory
if (pb.dirInfo.ioFlAttrib & ioDirMask)
{
// SUBDIRECTORY
// call myself to find its size and add that to the total
totalSize += SizeDirectory (vRefNum, pb.dirInfo.ioDrDirID);
}
else
{
// FILE
// take the •physical• sizes of the data and resource forks
totalSize += pb.hFileInfo.ioFlPyLen + pb.hFileInfo.ioFlRPyLen;
}
}
return totalSize;
}